package com.tarena.lbs.business.servcie.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.dao.repository.StoreRepository;
import com.tarena.lbs.business.manager.BasicOutputSourceManager;
import com.tarena.lbs.business.pojo.param.StoreParam;
import com.tarena.lbs.business.pojo.param.UserLocationParam;
import com.tarena.lbs.business.pojo.po.StorePO;
import com.tarena.lbs.business.pojo.query.AreaStoreQuery;
import com.tarena.lbs.business.pojo.query.StoreQuery;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.business.servcie.StoreService;
import com.tarena.lbs.common.enums.Roles;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StoreServiceImpl implements StoreService {
    @DubboReference
    private UserApi userApi;
    @Autowired
    private StoreRepository storeRepository;
    @Autowired
    private BasicOutputSourceManager basicOutputSourceManager;

    @Override
    public int save(StoreParam param) throws BusinessException {
        log.debug("保存店铺数据:{}", param);
        Integer businessId = checkAndGetBusinessId();
        Asserts.isTrue(businessId == null, new BusinessException("-2", "商家不存在无法绑定"));
        StorePO storePO = new StorePO();
        BeanUtils.copyProperties(param, storePO);
        int i = storeRepository.save(storePO);
        return i;
    }

    private Integer checkAndGetBusinessId() throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("-2", "用户认证解析失败"));
        Roles role = userPrinciple.getRole();
        Integer businessId = null;
        AdminDto adminDto = userApi.getAdminById(userPrinciple.getId());
        if (role == Roles.SHOP) {
            businessId = adminDto.getBusinessId();
        }
        return businessId;
    }

    @Override
    public PageResult<StoreVO> pageList(StoreQuery query) throws BusinessException {
        log.debug("开始查询店铺列表，查询参数：{}", query);
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("-2", "用户认证解析失败"));
        Roles role = userPrinciple.getRole();
        if (role == Roles.SHOP) {
            Integer businessId = userApi.getAdminById(userPrinciple.getId()).getBusinessId();
            if (businessId == null) {
                new BusinessException("-2", "商家不存在无法绑定");
            }
            query.setBusinessId(businessId);
            PageResult<StoreVO> voPage = new PageResult<>();
            PageInfo<StorePO> pageInfo = storeRepository.pagesList(query);
            voPage.setPageNo(pageInfo.getPageNum());
            voPage.setPageSize(pageInfo.getPageSize());
            voPage.setTotal(pageInfo.getTotal());
            List<StoreVO> vos = null;
            List<StorePO> pos = pageInfo.getList();
            if (pos != null && pos.size() > 0) {
                voPage.setObjects(pos.stream().map(po -> {
                    StoreVO vo = new StoreVO();
                    BeanUtils.copyProperties(po, vo);
                    return vo;
                }).collect(Collectors.toList()));
            }
            return voPage;
        }
        return null;
    }

//    @Override
//    public void location(UserLocationParam param) throws BusinessException {
//        //1.检查并且获取userId
//        Integer userId = checkAndGetUserId();
//        //2.利用定位数据获取 es中前5个店铺信息 需要es的geoDistance帮助我们完成任务
//        List<StoreSearchEntity> stores=getNearStores(param);
//        log.info("上报定位查询到的店铺信息:{}",stores);
//        //3.封装 消息事件 发送到总线中
//        MessageChannel channel = outputSource.storeLocationOutput();
//        //消息体的数据 封装准备的 原则  准确 精简
//        //准确 消息内容 足够使得消费者完成业务
//        //精简 在保证准确的前提下 尽可能缩小消息数据的体量
//        //3.1如果定位查询店铺 非空 组织消息 发送消息
//        if (stores!=null&&stores.size()>0){
//            for (StoreSearchEntity store : stores) {
//                LocationEvent event=new LocationEvent();
//                event.setUserId(userId);
//                event.setStoreId(store.getId());
//                channel.send(MessageBuilder.withPayload(event).build());
//                log.info("成功发送用户定位店铺信息到总线:{}",event);
//            }
//        }
//        //3.2如果定位查询店铺 为空 什么都不做
//    }
    private Integer checkAndGetUserId() throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","用户认证解析失败"));
        return userPrinciple.getId();
    }

    @Override
    public PageResult<StoreVO> getAreaStoreList(AreaStoreQuery query) throws BusinessException {
        //1.检查认证结果 获取商家账号对应商家id
        Integer businessId = checkAndGetBusinessId();
        //2.组织sql的where条件 查询满足区域 满足businessId的店铺列表
        List<StorePO> pos = getAreaStores(query, businessId);
        //3.封装分页对象
        return assemblePageResult(pos);
    }

    private PageResult<StoreVO> assemblePageResult(List<StorePO> pos) {
        PageResult<StoreVO> voPage = new PageResult<>(10, 1);
        voPage.setTotal(100L);
        if (pos != null && pos.size() > 0) {
            voPage.setObjects(pos.stream().map(po -> {
                StoreVO vo = new StoreVO();
                BeanUtils.copyProperties(po, vo);
                return vo;
            }).collect(Collectors.toList()));
        }
        return voPage;
    }
    private List<StorePO> getAreaStores(AreaStoreQuery areaStoreQuery,Integer businessId){
        //组织调用的sql语句 where条件拼接
        QueryWrapper<StorePO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("business_id",businessId).and(
                wq->wq.in("province_id",areaStoreQuery.getCityIdList()).
                        or().in("city_id",areaStoreQuery.getCityIdList()).
                        or().in("area_id",areaStoreQuery.getCityIdList())
        );
        return storeRepository.list(queryWrapper);
    }
}
